fix(rt): closure aggregate + #setTupleArgs fallback#952
Open
fix(rt): closure aggregate + #setTupleArgs fallback#952
Conversation
Add a rule for `aggregateKindClosure` to construct closures as `Aggregate(variantIdx(0), ARGS)`, matching the existing tuple and ADT aggregate handling. Add an `[owise]` fallback to `#setTupleArgs` for `Value` arguments that are not wrapped in an `Aggregate` tuple. This handles closure-call paths where a single argument is passed directly. Test: `closure-no-capture.rs` — a non-capturing closure passed through a generic `FnOnce` call. Exercises the `#setTupleArgs` fallback for unwrapped single-value arguments. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
dkcumming
reviewed
Mar 2, 2026
Collaborator
dkcumming
left a comment
There was a problem hiding this comment.
Just commenting for now sorry, I need to look closer tomorrow. But just mentioning that the link you sent was from current rust MIR (fine in this case) but for clarity the AggregateKind we are representing is this Stable MIR one. Also I think the assert would be good in the test to see that the data is correctly manipulated
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add three semantics fixes needed by the closure-call path, plus a regression test:
aggregateKindClosurereduction:ARGS:List ~> #mkAggregate(aggregateKindClosure(...)) => Aggregate(variantIdx(0), ARGS)#setTupleArgs(IDX, VAL:Value) [owise]fallback for unwrapped single-value argumentssetupCalleeClosure3(withisFunTypepredicate)closure-no-capture.rsregression testContext
Stable MIR represents closure construction via
Rvalue::Aggregate(AggregateKind::Closure(...)). The K semantics had rules for tuple/ADT aggregates, but no rule foraggregateKindClosure.For closure calls, argument placement goes through
#setTupleArgs. Existing rules only handled tuple/list-shaped payloads.Also, once closure type metadata is present, closure env locals can be typed as
Ref<FunType(...)>. Before this PR, closure setup rules only matchedVoidType-based closure typing paths, so the typed closure path needed an explicit setup rule.Red vs Green for
aggregateKindClosureRED:
No matching rule, execution is stuck.
GREEN:
aggregateKindClosurereduces toAggregate(variantIdx(0), ARGS), so closure aggregate construction proceeds.Red vs Green for
#setTupleArgs [owise]After closure aggregate reduction is added, execution advances to the next blocker:
RED (next blocker):
No existing
#setTupleArgsrule matches this plainValueshape.GREEN:
The fallback
handles the unwrapped single-value case and allows argument setup to continue.
Red vs Green for
setupCalleeClosure3With typed closure metadata, closure env can appear as
Ref<FunType(...)>. Existing closure setup rules were guarded forVoidTypeclosure typing paths, so typed closure setup could miss those rules.RED:
Typed closure env path does not satisfy the existing
VoidTypeguard shape for closure setup, so closure-call setup does not reliably take the typed closure path.GREEN:
setupCalleeClosure3adds the typed path explicitly:isFunType(#lookupMaybeTy(pointeeTy(...)))#setTupleArgs(2, getValue(LOCALS, TUPLE))This keeps closure-call argument placement consistent when closure env typing is known.
Proof evidence
Without fix (RED):
closure-no-capture.rsgets stuck on closure aggregate, and after adding only the closure aggregate rule it gets stuck at#setTupleArgs(2, Integer(41,8,false)).With fix (GREEN):
Test plan
test_prove_rs[closure-no-capture]make test-integrationregression